
import { _decorator, Component, Node, Prefab, NodePool, instantiate, Vec2, Vec3, tween, view, Size, EditBox } from 'cc';
import { DEV } from 'cc/env';
const { ccclass, property } = _decorator;

import  {CardsFlipToFrontOrBack} from './CardsFlipToFrontOrBack';

@ccclass('CardsFly')
export class CardsFly extends Component {
    @property({displayName: DEV && 'startNode节点', type: Node})
    startNode !: Node;

    @property({displayName: DEV && 'endNode节点', type: Node})
    endNode !: Node;

    @property({displayName: DEV && 'cardsFlyPrefab预制体', type: Prefab})
    cardsFlyPrefab !: Prefab;

    @property(EditBox)
    minNumEditBox !: EditBox;

    @property(EditBox)
    maxNumEditBox !: EditBox;

    @property(EditBox)
    radiusNumEditBox !: EditBox;

    cardsFlyPool !: NodePool; //缓冲池
    viewWinSize : Size = new Size(); //可见区域
    startNodeUIPos : Vec3 = new Vec3(); //起点位置
    endNodeUIPos : Vec3 = new Vec3(); //终点位置
    isRandomGenerate : boolean = true; //勾选(围绕起点随机生成)

    onLoad () {
        this.cardsFlyPool = new NodePool();//实例化缓冲池
        this.viewWinSize = view.getVisibleSize();

        this.initCardsFlyPool();

        // this.startNode.on(Node.EventType.TOUCH_MOVE, this.onNodeMoveEvent, this);//拖拽移动屏幕位置
        // this.endNode.on(Node.EventType.TOUCH_MOVE, this.onNodeMoveEvent, this);
    }

    initCardsFlyPool (count : number = 20) : void {
        for (let i = 0; i < count; i++) {
            let cardsFly = instantiate(this.cardsFlyPrefab);//instantiate: 克隆指定的任意类型的对象。
            this.cardsFlyPool.put(cardsFly);//put: 获取对象池中的对象，如果对象池没有可用对象，则返回空。
        }
    }

    /**
     * 发牌落地点X轴 = 子节点最后一个牌位置X轴 + Math.abs(spacingx)/2（X轴正方向发牌）
     * @returns 返回发牌落牌的位置
     */
    getNextPosInChildren (): Vec3 {
        let layoutNode = this.endNode;
        let len = layoutNode.children.length;//查找有多少个子节点
        
        if (len == 0){ return layoutNode.getPosition()} // 没有子节点就是父节点的位置
        let x = layoutNode.children[len-1].getPosition().x ;//还是有坐标误差
        let nextPos = new Vec3(x, layoutNode.getPosition().y, layoutNode.getPosition().z);
        return nextPos
    }

    playAnim() {
        // console.log("开始playAnim")
        const minNum = parseInt(this.minNumEditBox.string) || 1;//获取输入值 || 默认值(提示：想发多少就发多少)
        const maxNum = parseInt(this.maxNumEditBox.string) || 1;
        const diffNum = maxNum - minNum;
        const radiusNum = parseInt(this.radiusNumEditBox.string) || 10;//生成的半径范围

        let randomCount = Math.random() * diffNum + minNum;//最小值到最大值的随机数 + 最小值
        let startPos = this.startNode.getPosition();//获取起点位置
        // let endPos = this.endNode.getPosition();
        let endPos = this.getNextPosInChildren();
        this.playCardsFlyAnim(randomCount, startPos, endPos, radiusNum);
        
    }
    
    async playCardsFlyAnim(count: number, stPos: Vec3, edPos: Vec3, r: number = 1) {
        // console.log("playCardsFlyAnim参数："+"\n 1: "+count+"\n 2: "+stPos+"\n 3: "+edPos+"\n 4: "+r)
        // 确保当前节点池有足够的数量
        const poolSize = this.cardsFlyPool.size();
        const reCreateCardsFlyCount = poolSize > count ? 0 : count - poolSize;
        this.initCardsFlyPool(reCreateCardsFlyCount);

        // 生成圆，并且对圆上的点进行排序
        let points = this.getCirclePoints(r, stPos, count);
        let cardsFlyNodeList = points.map((pos) => {
            let startCards = this.cardsFlyPool.get()!;
            startCards.setPosition(stPos);
            this.node.addChild(startCards);
            // 防止pos因为pos.subtract被更改，使用clone复制
            const tempPos = pos.clone(); 
            return { node: startCards, stPos: stPos, mdPos: pos, edPos: edPos, dis: tempPos.subtract(edPos).length() };
        });
        cardsFlyNodeList = cardsFlyNodeList.sort((a, b) => {
            if (a.dis - b.dis > 0) return 1;
            if (a.dis - b.dis < 0) return -1;
            return 0;
        });

        // 执行落袋的动画
        cardsFlyNodeList.forEach((item, idx) => {
            tween(item.node).stop();
            item.node.setPosition(item.stPos);
            // console.log("执行落袋的动画: "+ item.node)
            tween(item.node)
                .to(0.3, { position: item.mdPos})
                .delay(idx * 0.1)
                .to(0.5, { position: item.edPos})
                // .to(0.5, { position: item.edPos, scale: new Vec3(0.6, 0.6, 0.6)})
                .call( async ()=>{
                    this.cardsFlyPool.put(item.node!);  //牌落地消失

                    let cards = instantiate(this.cardsFlyPrefab);//instantiate: 克隆指定的任意类型的对象。
                    this.endNode.addChild(cards);//添加子节点
                    // console.log("执行落袋的动画call: "+ item.node)
                    await new CardsFlipToFrontOrBack().flipToFront(cards);//真正的牌在这里

            }).start();
        });
    }

    /**
     * 以某点为圆心，生成圆周上等分点的坐标
     *
     * @param {number} r 半径
     * @param {cc.Vec3} pos 圆心坐标
     * @param {number} count 等分点数量
     * @param {number} [randomScope=80] 等分点的随机波动范围
     * @returns {cc.Vec2[]} 返回等分点坐标
     * 
     */
    getCirclePoints (r: number, pos: Vec3, count: number, randomScope: number = 10): Vec3[] {
        let points = [];
        let radians = (Math.PI / 180) * Math.round(360 / count);
        for (let i = 0; i < count; i++) {
            let x = pos.x + r * Math.sin(radians * i);
            let y = pos.y + r * Math.cos(radians * i);
            if (this.isRandomGenerate) {
                points.unshift(new Vec3(x + Math.random() * randomScope, y + Math.random() * randomScope, 0));
            } else {
                points.unshift(new Vec3(x, y, 0));
            }
        }
        // console.log("points: "+ points)
        return points;
    }

    //拖拽起点和终点坐标位置
    onNodeMoveEvent (evt: any) {
        // console.log("evt: "+ evt)
        let localPos = evt.getUILocation();
        let target = evt.target;
        let setPosX = localPos.x - this.viewWinSize.width / 2;
        let setPosY = localPos.y - this.viewWinSize.height / 2;
        target.setPosition(setPosX, setPosY, 0);
    }

}
